<template>
  <div class="container">
    <!-- 面包屑区域 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 卡片区域 -->
    <el-card>
      <!-- 添加用户按钮 -->
      <el-button type="primary" round @click="addRoleFormBool = true">新增管理员角色</el-button>
      <!-- 角色列表展示 -->
      <el-table
        :data="rolesLise"
        stripe
        border
        style="width: 100%">
        <el-table-column type="expand">
          <!-- 三级权限展示 -->
          <template slot-scope="scope">
            <el-row :class="['bdLR','rcenter','bdBtm', i1 == 0 ? 'bdTop' : '']" :span="24" v-for="(itemA, i1) in scope.row.children" :key="itemA.id">
              <!-- 第一列：一级权限-->
              <el-col :span="4" class="ccenter">
                <el-tag
                closable
                effect="light"
                @close="handleDelRoleRight(scope.row, itemA)">
                  {{itemA.authName}}
                </el-tag>
                <i class="el-icon-caret-right mg"></i>
              </el-col>
              <!-- 第二列-->
              <el-col :span="20">
                <el-row :span="24"  :class="['bdLeft','rcenter', i2 == 0 ? '' : 'bdTop']" v-for="(itemB, i2) in itemA.children" :key="itemB.id">
                  <!-- 外围第二列内部每行第一列: 二级权限 -->
                  <el-col :span="5" class="ccenter">
                    <el-tag
                    closable
                    effect="light"
                    type="success"
                    @close="handleDelRoleRight(scope.row, itemB)">
                      {{itemB.authName}}
                    </el-tag>
                    <i class="el-icon-caret-right mg"></i>
                  </el-col>
                  <!-- 外围第二列内部每行第二列: 三级权限 -->
                  <el-col :span="19">
                    <el-tag
                    closable
                    effect="light"
                    type="warning"
                    class="around"
                    v-for="itemC in itemB.children"
                    :key="itemC.id"
                    @close="handleDelRoleRight(scope.row, itemC)">
                      {{itemC.authName}}
                    </el-tag>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-table-column>
        <el-table-column
        type="index"
        align="center"></el-table-column>
        <el-table-column
          prop="roleName"
          label="角色名称"
          header-align="center">
        </el-table-column>
        <el-table-column
          prop="roleDesc"
          label="角色描述"
          header-align="center">
        </el-table-column>
        <el-table-column
          label="操作"
          width="290"
          align="center"
          header-align="center">
          <template slot-scope="scope">
            <el-button type="primary" icon="el-icon-edit" size="mini" @click="handleEditRole(scope.row)">编辑</el-button>
            <el-button type="danger" icon="el-icon-delete" size="mini" @click="handleDelRole(scope.row)">删除</el-button>
            <el-button type="warning" icon="el-icon-setting" size="mini" @click="handleDistRight(scope.row)">分配权限</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 新增管理员角色弹出框 -->
    <el-dialog title="新增管理员角色" :visible.sync="addRoleFormBool" @close="addRoleFormClose">
      <el-form :model="addRoleForm" status-icon ref="addRoleFormRef" :rules="addRoleRules" label-position="right"  label-width="110px">
        <el-form-item label="新增角色名称" prop="roleName" label-width="110px">
          <el-input v-model="addRoleForm.roleName" placeholder="请输入新增的角色名称..."></el-input>
        </el-form-item>
        <el-form-item label="角色功能描述" prop="roleDesc" label-width="110px">
          <el-input v-model="addRoleForm.roleDesc" placeholder="请对新增角色功能权限进行简单描述..."></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="addRoleFormBool = false">取 消</el-button>
        <el-button type="primary" @click="addRoleFormSubmit">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 编辑管理员角色弹出框 -->
    <el-dialog :title="`编辑当前角色【${roleName}】`" :visible.sync="editRoleFormBool" @close="editRoleFormClose">
      <el-form :model="editRoleForm" status-icon ref="editRoleFormRef" :rules="editRoleRules" label-position="right"  label-width="110px">
        <el-form-item label="当前角色名称" prop="roleName" label-width="110px">
          <el-input v-model="editRoleForm.roleName"></el-input>
        </el-form-item>
        <el-form-item label="当前角色描述" prop="roleDesc" label-width="110px">
          <el-input v-model="editRoleForm.roleDesc"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="editRoleFormBool = false">取 消</el-button>
        <el-button type="primary" @click="editRoleFormSubmit">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 为角色分配权限弹出框 -->
    <el-dialog :title="`为当前【${roleName}】分配管理权限`" :visible.sync="distRightTreeBool" @close="distRightTreeClose">
      <!-- 树形权限选择器 -->
      <el-tree
        :data="treeRightsData"
        ref="treeRightsRef"
        show-checkbox
        default-expand-all
        node-key="id"
        :default-checked-keys="initCheckedArr"
        :props="defaultProps">
      </el-tree>
      <div slot="footer">
        <el-button @click="distRightTreeBool = false">取 消</el-button>
        <el-button type="primary" @click="distRightTreeSubmit">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'RouleList',
  created () {
    this.getRolesList()
  },
  data () {
    return {
      // 角色列表
      rolesLise: [],
      // 新增角色弹出框
      addRoleFormBool: false,
      // 编辑角色弹出框
      editRoleFormBool: false,
      // 分配角色弹出框
      distRightTreeBool: false,
      // 新增角色信息
      addRoleForm: {
        roleName: '',
        roleDesc: ''
      },
      // 编辑角色信息
      editRoleForm: {},
      // 新增角色表单自定义校验规则
      addRoleRules: {
        roleName: [
          { required: true, message: '角色为必填项', trigger: 'blur' },
          { max: 10, message: '角色名称不能超过10个字符', trigger: 'blur' }
        ]
      },
      // 编辑角色表单自定义校验规则
      editRoleRules: {
        roleName: [
          { required: true, message: '角色名称为必填项', trigger: 'blur' },
          { max: 10, message: '角色名称不能超过10个字符', trigger: 'blur' }
        ]
      },
      // 树形权限列表数据源
      treeRightsData: [],
      // 树形权限列表配置项
      defaultProps: {
        label: 'authName'
      },
      // 用户初始权限
      initCheckedArr: [],
      // 保存当前正在操作的角色ID
      roleId: '',
      // 保存当前正在操作角色名
      roleName: ''
    }
  },
  methods: {
    // 获取用户角色列表
    async getRolesList () {
      const { data: res } = await this.$http.get('roles')
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.rolesLise = res.data
    },
    // 请求服务器新增角色
    addRoleFormSubmit () {
      this.$refs.addRoleFormRef.validate(async valid => {
        if (!valid) return this.$message.error('信息存在不合法内容')
        this.addRoleFormBool = false
        const { data: res } = await this.$http.post('roles', this.addRoleForm)
        if (res.meta.status !== 201) return this.$message.error(res.meta.msg)
        this.$message.success(res.meta.msg)
        this.getRolesList()
      })
    },
    // 关闭弹框重置表单内容
    addRoleFormClose () {
      this.$refs.addRoleFormRef.resetFields()
    },
    // 编辑角色弹框获取当前角色信息
    async handleEditRole (currRole) {
      this.editRoleFormBool = true
      this.roleName = currRole.roleName
      if (!currRole.id) return this.$message.error('用户数据异常，请重试！')
      const { data: res } = await this.$http.get(`roles/${currRole.id}`)
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      sessionStorage.setItem('isRole', JSON.stringify(res.data))
      this.editRoleForm = res.data
    },
    // 角色信息修改
    editRoleFormSubmit () {
      this.$refs.editRoleFormRef.validate(async valid => {
        if (!valid) return this.$message.error('存在不合法信息')
        const isRole = JSON.parse(sessionStorage.getItem('isRole'))
        if (this.editRoleForm.roleName === isRole.roleName && this.editRoleForm.roleDesc === isRole.roleDesc) return this.$message.error('信息未更新，请勿频繁提交！')
        const { data: res } = await this.$http.put(`roles/${this.editRoleForm.roleId}`, this.editRoleForm)
        this.editRoleFormBool = false
        if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
        this.getRolesList()
        this.$message.success(res.meta.msg)
      })
    },
    // 删除角色信息
    async handleDelRole (currRole) {
      if (!currRole) return this.$message.error('用户数据异常！')
      const roleName = currRole.roleName
      const confirmRes = await this.$confirm(`确认永久删除 ${roleName} 角色?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).catch(err => err)
      if (confirmRes !== 'confirm') return this.$message.info(`对 ${roleName} 角色的删除操作被终止！`)
      const { data: res } = await this.$http.delete(`roles/${currRole.id}`)
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.$message.success(res.meta.msg)
      this.getRolesList()
    },
    // 删除角色指定权限
    async handleDelRoleRight (role, right) {
      const roleName = role.roleName
      const rightName = right.authName
      if (!(role && right)) return this.$message.warning('用户数据异常,请稍后重新尝试!')
      const confirmRes = await this.$confirm(`确定要取消【${roleName}】角色的【${rightName}】权限吗?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).catch(err => err)
      if (confirmRes !== 'confirm') return this.$message.info(`【${roleName}】角色【${rightName}】权限的取消操作被终止!`)
      const { data: res } = await this.$http.delete(`roles/${role.id}/rights/${right.id}`)
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      role.children = res.data
      this.$message.success(res.meta.msg)
    },
    // 为角色分配权限
    async handleDistRight (roleInfo) {
      this.distRightTreeBool = true
      this.roleId = roleInfo.id
      this.roleName = roleInfo.roleName
      // 获取树形所有权限为Tree提供数据支撑
      const { data: res } = await this.$http.get('rights/tree')
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.treeRightsData = res.data
      this.recGetrightId(roleInfo, this.initCheckedArr)
    },
    // 递归获取当前用户拥有权限id数组
    recGetrightId (roleinfo, newArr) {
      const node = roleinfo.children
      if (!node) {
        return newArr.push(roleinfo.id)
      }
      node.forEach(item => { this.recGetrightId(item, newArr) })
    },
    // 判断两个数组中元素是否相同
    isSameArr (arrA, arrB) {
      let flag = true
      arrA.forEach(itemA => {
        if (arrB.indexOf(itemA) === -1) {
          flag = false
        }
      })
      arrB.forEach(itemB => {
        if (arrA.indexOf(itemB) === -1) {
          flag = false
        }
      })
      return flag
    },
    // 提交角色授权权限
    async distRightTreeSubmit () {
      const hitCheckedArr = this.$refs.treeRightsRef.getCheckedKeys()
      const halfCheckedArr = this.$refs.treeRightsRef.getHalfCheckedKeys()
      const confirmRightsList = [
        ...hitCheckedArr,
        ...halfCheckedArr
      ]
      // 只获取最新的最后一级校色权限选中项的ID
      const newHitCheckedArr = this.$refs.treeRightsRef.getCheckedKeys(true)
      const flag = this.isSameArr(this.initCheckedArr, newHitCheckedArr)
      if (flag) return this.$message.warning('权限未修改,请勿频繁提交!')
      if (!confirmRightsList) return this.$message.error('数据异常,请稍后重试!')
      // 服务器需求以 `,` 分割的权限 ID 列表（字符串）结构数据
      const confirmRightsListStr = confirmRightsList.join(',')
      const { data: res } = await this.$http.post(`roles/${this.roleId}/rights`, { rids: confirmRightsListStr })
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.distRightTreeBool = false
      this.$message.success(res.meta.msg)
      this.getRolesList()
    },
    // 关闭角色分配权限弹出框将当前默认选中清空
    distRightTreeClose () {
      this.initCheckedArr = []
    },
    // 关闭编辑角色弹出框清除当前校验规则提示信息
    editRoleFormClose () {
      this.$refs.editRoleFormRef.resetFields()
    }
  }
}
</script>
<style lang="less" scoped>
.el-breadcrumb {
  margin-bottom: 12px;
}
.el-card {
  .el-table {
      margin-top: 12px;
  }
}
// Tree树形结构取消动画
.el-tree {
  transition: 0;
}
// 权限列表样式
.bdBtm {
  border-bottom: 1px solid #eeeeee;
}
.bdTop {
  border-top: 1px solid #eeeeee;
}
.bdLeft {
  border-left: 1px solid #eeeeee;
}
.bdLR {
  border-right: 1px solid #eeeeee;
  border-left: 1px solid #eeeeee;
}
.rcenter {
  display: flex;
  align-items: center;
}
.ccenter {
  display: flex;
  justify-content: center;
  align-items: center;
}
.around {
  margin: 7px;
}
.mg {
  margin-left: 8px;
}
.el-tag {
  transition: 1.5s;
}
</style>
